home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- subject.c
-
- This module handles subject windows.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
-
- #include "glob.h"
- #include "subject.h"
- #include "child.h"
- #include "mark.h"
- #include "news.h"
- #include "newswatcher.h"
- #include "dialog.h"
- #include "status.h"
- #include "menus.h"
- #include "next.h"
- #include "ldef.h"
- #include "article.h"
- #include "collapse.h"
- #include "drawutil.h"
- #include "memutil.h"
- #include "listutil.h"
- #include "windutil.h"
- #include "thread.h"
- #include "tescroll.h"
- #include "cancel.h"
- #include "header.h"
- #include "wind.h"
- #include "strutil.h"
- #include "message.h"
- #include "fileutil.h"
- #include "group.h"
- #include "olddrag.h"
- #include "dragutil.h"
- #include "print.h"
- #include "key.h"
- #include "teutil.h"
- #include "search.h"
- #include "ic.h"
- #include "help.h"
-
-
-
- #define kMinWindowWidth 320 /* minimum window width */
-
- #define kExtractBinariesManuallyDlg 149
- #define kExtractBinariesManuallyLabelItem 3
- #define kExtractBinariesManuallyListItem 4
-
-
-
- static ListHandle gExtractBinariesManuallyList;
-
- static Boolean gFirstListClickCall; /* true if first call to ClickLoop function */
- static OSErr gClickLoopErr; /* click loop error code */
- static WindowPtr gDragSrcWindow; /* pointer to drag source window */
- static FSSpec gDragTheFile; /* file spec for saved dragged subjects */
- static Boolean gDraggedToFinder; /* true if subjects dragged to Finder */
- static short gDragDestRow; /* destination row when dragging subjects
- in extract binaries manually dialog */
-
- static ListClickLoopUPP gExtractBinariesManuallyClickLoopUPP;
- static ListClickLoopUPP gOldListClickLoopUPP;
- static ListClickLoopUPP gSubjectListClickLoopUPP;
- static DragTrackingHandlerUPP gExtractBinariesManuallyHandleTrackingUPP;
- static DragReceiveHandlerUPP gExtractBinariesManuallyHandleReceiveUPP;
- static DragSendDataUPP gDragSubjectsSendProcUPP;
- static ModalFilterUPP gExtractBinariesManuallyDialogFilterUPP;
- static UserItemUPP gExtractBinariesManuallyDlgLabelUserItemUPP;
- static UserItemUPP gExtractBinariesManuallyDlgListUserItemUPP;
-
-
-
- /*----------------------------------------------------------------------------
- GetSubjects
-
- Get a range of subject headers from the news server and store them in
- a subject array.
-
- Entry: newsGroup = name of the group.
- first = first article number to get.
- last = last article number to get.
- subjectArray = handle to subject array.
- index = index in subject array to store first subject.
- strings = handle to strings block.
- *nextStringOffset = offset of next available location in
- strings block.
-
- Exit: function result = error code.
- *numFetched = number of subjects fetched.
- *nextStringOffset updated.
-
- The caller must preallocate memory in the subject array for at least
- (last-first+1) new subjects.
-
- If the group does not exist the function result is true and
- *numFetched=0.
- ----------------------------------------------------------------------------*/
-
- static OSErr GetSubjects (char *newsGroup, long first, long last,
- TSubject **subjectArray, short index,
- Handle strings, long *nextStringOffset,
- short *numFetched)
- {
- THeader **headers = nil;
- long numHeaders;
- TSubject theSubject;
- THeader *pHeader, *pHeaderEnd;
- TSubject *pSubject;
- Handle str = nil;
- long strLen;
- long offset;
- OSErr err = noErr;
-
- err = GetHeaders(newsGroup, "SUBJECT", first, last, &headers, &str, &numHeaders);
- if (err != noErr) return err;
- if (headers == nil) {
- *numFetched = 0;
- return noErr;
- }
-
- strLen = MyGetHandleSize(str);
- offset = *nextStringOffset;
- err = MyHandAndHand(str, strings);
- if (err != noErr) goto exit;
- *nextStringOffset += strLen;
-
- pHeaderEnd = *headers + numHeaders;
- pSubject = *subjectArray + index;
- for (pHeader = *headers; pHeader < pHeaderEnd; pHeader++, pSubject++, index++) {
- theSubject.subjectOffset = pHeader->offset + offset;
- theSubject.authorOffset = -1;
- theSubject.number = pHeader->number;
- theSubject.collapsed = gPrefs.showThreadsCollapsed;
- theSubject.read = false;
- theSubject.inList = true;
- theSubject.drawTriangleFilled = false;
- theSubject.onlyRedrawTriangle = false;
- theSubject.onlyRedrawCheck = false;
- *pSubject = theSubject;
- }
-
- MyDisposeHandle(headers);
- MyDisposeHandle(str);
- *numFetched = numHeaders;
- return noErr;
-
- exit:
-
- MyDisposeHandle(str);
- MyDisposeHandle(headers);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetAuthors
-
- Get a range of author headers from the news server and store them in
- a subject array.
-
- Entry: newsGroup = name of the group.
- first = first article number to get.
- last = last article number to get.
- subjectArray = handle to subject array.
- index = starting index in subject array.
- num = number of subject records.
- strings = handle to strings block.
- *nextStringOffset = offset of next available location in
- strings block.
-
- Exit: function result = error code.
- *nextStringOffset updated.
-
- GetSubjects must be called before GetAuthors to initialize the
- subject array elements.
- ----------------------------------------------------------------------------*/
-
- static OSErr GetAuthors (char *newsGroup, long first, long last,
- TSubject **subjectArray, short index, short num,
- Handle strings, long *nextStringOffset)
- {
- THeader **headers = nil;
- long numHeaders;
- THeader *pHeader, *pHeaderEnd;
- TSubject *pSubject, *pSubjectEnd;
- Handle str = nil;
- long strLen;
- long offset;
- OSErr err = noErr;
-
- err = GetHeaders(newsGroup, "FROM", first, last, &headers, &str, &numHeaders);
- if (err != noErr) return err;
- if (headers == nil) return noErr;
-
- strLen = MyGetHandleSize(str);
- offset = *nextStringOffset;
- err = MyHandAndHand(str, strings);
- if (err != noErr) goto exit;
- *nextStringOffset += strLen;
-
- pHeader = *headers;
- pHeaderEnd = *headers + numHeaders;
- pSubject = *subjectArray + index;
- pSubjectEnd = pSubject + num;
- while (pHeader < pHeaderEnd && pSubject < pSubjectEnd) {
- if (pHeader->number < pSubject->number) {
- pHeader++;
- } else if (pHeader->number > pSubject->number) {
- pSubject++;
- } else {
- pSubject->authorOffset = pHeader->offset + offset;
- pHeader++;
- pSubject++;
- }
- }
-
- MyDisposeHandle(headers);
- MyDisposeHandle(str);
- return noErr;
-
- exit:
-
- MyDisposeHandle(headers);
- MyDisposeHandle(str);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetSubjectsAndAuthorsFromNet
-
- Get unread subjects and authors for a group from the NNTP server.
-
- Entry: groupName = the group name.
- theGroup = pointer to the group record.
- groupKind = kind of group (kFullGroup, kNewGroup, or kUserGroup).
- maxFetch = maximum number of articles to fetch.
-
- Exit: function result = error code.
- *subjectArray = handle to subject array, with the fields
- subjectOffset, authorOffset, number, read, and inList initialized.
- *numSubjects = number of subjects fetched.
- *subjectStrings = handle to subject strings.
- *firstFetched = article number of first article fetched.
-
- If the group does not exist, the function result is true and
- *numSubjects = 0. In other words, a deleted group is treated the
- same as a group with no unread articles.
- ----------------------------------------------------------------------------*/
-
- static OSErr GetSubjectsAndAuthorsFromNet (char *groupName, TGroup *theGroup,
- TGroupWindowKind groupKind, short maxFetch,
- TSubject ***subjectArray, short *numSubjects,
- Handle *subjectStrings, long *firstFetched)
- {
- TSubject **array = nil;
- short index = 0;
- Handle strings = nil;
- OSErr err = noErr;
- long nextStringOffset = 0;
- TUnread **unread;
- long first, last, numToFetch, totNumToFetch;
- short numAllocated;
- short numFetched;
-
- err = MyNewHandle(100*sizeof(TSubject), &array);
- if (err != noErr) goto exit;
- numAllocated = 100;
- err = MyNewHandle(0, &strings);
- if (err != noErr) goto exit;
-
- if (groupKind == kUserGroup) {
- unread = theGroup->unread;
- totNumToFetch = theGroup->numUnread;
- first = (**unread).firstUnread;
- last = (**unread).lastUnread;
- if (totNumToFetch > maxFetch) {
- while (unread != nil) {
- totNumToFetch -= last - first + 1;
- if (totNumToFetch <= maxFetch) {
- first = last - (maxFetch - totNumToFetch) + 1;
- break;
- }
- unread = (**unread).next;
- if (unread != nil) {
- first = (**unread).firstUnread;
- last = (**unread).lastUnread;
- }
- }
- }
- *firstFetched = first;
- while (unread != nil) {
- numToFetch = last - first + 1;
- if (index + numToFetch > numAllocated) {
- numAllocated = index + numToFetch + 100;
- err = MySetHandleSize(array, numAllocated*sizeof(TSubject));
- if (err != noErr) goto exit;
- }
- err = GetSubjects(groupName, first, last, array, index, strings,
- &nextStringOffset, &numFetched);
- if (err != noErr) goto exit;
- if (gPrefs.showAuthors) {
- err = GetAuthors(groupName, first, last, array, index, numFetched, strings,
- &nextStringOffset);
- if (err != noErr) goto exit;
- }
- index += numFetched;
- unread = (**unread).next;
- if (unread != nil) {
- first = (**unread).firstUnread;
- last = (**unread).lastUnread;
- }
- }
- } else {
- first = theGroup->firstMess;
- last = theGroup->lastMess;
- numToFetch = last - first + 1;
- if (numToFetch > maxFetch) {
- numToFetch = maxFetch;
- first = last - numToFetch + 1;
- }
- *firstFetched = first;
- if (numToFetch > numAllocated) {
- numAllocated = numToFetch;
- err = MySetHandleSize(array, numAllocated*sizeof(TSubject));
- if (err != noErr) goto exit;
- }
- err = GetSubjects(groupName, first, last, array, index, strings,
- &nextStringOffset, &numFetched);
- if (err != noErr) goto exit;
- if (gPrefs.showAuthors) {
- err = GetAuthors(groupName, first, last, array, index, numFetched, strings,
- &nextStringOffset);
- if (err != noErr) goto exit;
- }
- index = numFetched;
- }
-
- MySetHandleSize(array, index*sizeof(TSubject));
- MySetHandleSize(strings, nextStringOffset);
-
- *subjectArray = array;
- *numSubjects = index;
- *subjectStrings = strings;
- return noErr;
-
- exit:
-
- MyDisposeHandle(array);
- MyDisposeHandle(strings);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FixHeight
-
- Round down window height to an exact multiple of lines.
-
- Entry: wind = pointer to subject window.
- *height = window height.
-
- Exit: *height = adjusted window height
- ----------------------------------------------------------------------------*/
-
- static void FixHeight (WindowPtr wind, short *height)
- {
- TWindow **info;
- short panelHeight, lineHeight, adjust;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- lineHeight = GetFontLineHeight(wind);
- adjust = panelHeight + 15;
- *height = (*height - adjust) / lineHeight * lineHeight + adjust;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MinHeight
-
- Compute the minimum height of a subject window.
-
- Entry: wind = pointer to subject window.
- ----------------------------------------------------------------------------*/
-
- static short MinHeight (WindowPtr wind)
- {
- TWindow **info;
- short lineHeight, height, extra;
-
- info = (TWindow**)GetWRefCon(wind);
- lineHeight = GetFontLineHeight(wind);
- extra = lineHeight + 15;
- if (extra < 65) extra = 65 + lineHeight;
- height = (**info).panelHeight + extra;
- FixHeight(wind, &height);
- return height;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Scroll
-
- Scroll a subject window.
-
- Entry: wind = pointer to subject window.
- part = part code.
- ----------------------------------------------------------------------------*/
-
- static void Scroll (WindowPtr wind, short part)
- {
- TWindow **info;
- ListHandle theList;
- short height, numCells;
- Cell theCell;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- height = (**theList).visible.bottom - (**theList).visible.top;
- numCells = (**theList).dataBounds.bottom;
- switch (part) {
- case inUpButton:
- case inDownButton:
- SetPt(&theCell, 0, 0);
- if (part == inUpButton) {
- theCell.v = GetFirstSelectedCell(theList);
- theCell.v--;
- if (theCell.v < 0) theCell.v = 0;
- } else {
- theCell.v = GetLastSelectedCell(theList);
- theCell.v++;
- if (theCell.v >= numCells) theCell.v = numCells-1;
- }
- SelectSingleListItem(theList, theCell);
- HandleUpdate(wind);
- MyLAutoScroll(theList);
- break;
- case inPageUp:
- MyLScroll(-(height - 1), theList);
- break;
- case inPageDown:
- MyLScroll(height - 1, theList);
- break;
- case kScrollToHome:
- MyLScroll(-numCells, theList);
- break;
- case kScrollToEnd:
- MyLScroll(numCells, theList);
- break;
- }
- KillBalloon();
- }
-
-
-
- /*----------------------------------------------------------------------------
- ResizeContents
-
- Adjust a group window's contents after a window size change (grow
- or zoom).
-
- Entry: wind = pointer to group window.
- ----------------------------------------------------------------------------*/
-
- static void ResizeContents (WindowPtr wind)
- {
- TWindow **info;
- short width, height, panelHeight;
- ListHandle theList;
- Point x;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- theList = (**info).theList;
- width = wind->portRect.right;
- height = wind->portRect.bottom;
-
- LSize(width-15, height-15-panelHeight, theList);
- SetPt(&x, width-15, (**theList).cellSize.v);
- LCellSize(x, theList);
-
- InvalRect(&wind->portRect);
-
- RecordNewLockedWindowPosition(wind, &gPrefs.subjectWindLocn);
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeNewWindow
-
- Create a new subject window.
-
- Entry: title = window title.
-
- Exit: function result = error code.
- *theWindow = pointer to new window.
- ----------------------------------------------------------------------------*/
-
- static OSErr MakeNewWindow (StringPtr title, WindowPtr *theWindow)
- {
- short width, height;
- WindowPtr wind = nil;
- TWindow **info;
- ListHandle theList;
- Point thePt;
- Rect listRect, sizeRect;
- short wid, checkMarkWidth, panelHeight;
- short tHeight, tWidth, x;
- FontInfo fInfo;
- TextStyle savedStyle;
- OSErr err;
- GrafPtr port;
-
- GetPort(&port);
-
- MyICReadSharedPrefs(kICListFont);
-
- err = CreateNewWindow(kSubject, title, gPrefs.listFont, gPrefs.listSize, &wind);
- if (err != noErr) return err;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = GetFontLineHeight(wind) + 9;
- (**info).panelHeight = panelHeight;
- (**info).authorsShown = gPrefs.showAuthors;
- width = kMinWindowWidth;
- height = MinHeight(wind);
- RestoreLockedWindowPosition(wind, width, height, gPrefs.subjectWindPosLocked,
- &gPrefs.subjectWindLocn);
- width = wind->portRect.right;
- height = wind->portRect.bottom;
-
- SetPt(&thePt, 0, 0);
- SetRect(&sizeRect, 0, 0, 1, 0);
- listRect = wind->portRect;
- listRect.top += panelHeight;
- listRect.right -= 15;
- listRect.bottom -= 15;
- theList = MyLNew(&listRect, &sizeRect, thePt, kLDEFProc, wind, false, true, false, true);
- (**theList).indent.h = 4;
- (**theList).selFlags |= lNoNilHilite;
- (**theList).refCon = (long)gListDefFuncUPP;
- (**info).theList = theList;
- (**info).vScroll = (**theList).vScroll;
-
- GetFontInfo(&fInfo);
- wid = CharWidth('9');
- GetPortTextStyle(&savedStyle);
- TextFont(systemFont);
- checkMarkWidth = CharWidth(checkMark);
- SetPortTextStyle(&savedStyle);
- tWidth = fInfo.ascent;
- if ((tWidth & 1) == 1) tWidth--;
- tHeight = tWidth >> 1;
- (**info).minusSignHCoord = ((tWidth - CharWidth('-')) >> 1) + 2;
- (**info).threadCountHCoord = x = 3*wid + tWidth;
- (**info).checkHCoord = x = x + 2*wid;
- if ((**info).authorsShown) {
- (**info).authorHCoord = x = x + 2*checkMarkWidth;
- (**info).authorWidth = 16*wid;
- (**info).subjectHCoord = x + 18*wid;
- } else {
- (**info).subjectHCoord = (**info).authorHCoord = x = x + 2*checkMarkWidth;
- }
- (**info).collapseTriangle = OpenPoly();
- MoveTo(0,0);
- LineTo(0,tWidth);
- LineTo(tHeight,tHeight);
- LineTo(0,0);
- ClosePoly();
- (**info).expandTriangle = OpenPoly();
- MoveTo(0,0);
- LineTo(tWidth,0);
- LineTo(tHeight,tHeight);
- LineTo(0,0);
- ClosePoly();
-
- (**info).autoExpandedThread = -1;
-
- *theWindow = wind;
- SetPort(port);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- RedrawSubjectWindowUnreadCount
-
- Force the panel are unread article count to be updated in a subject window.
-
- Entry: wind = pointer to suject list window.
- ----------------------------------------------------------------------------*/
-
- void RedrawSubjectWindowUnreadCount (WindowPtr wind)
- {
- TWindow **info;
- GrafPtr port;
- Rect r;
-
- GetPort(&port);
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
- r = wind->portRect;
- r.bottom = (**info).panelHeight - 4;
- InvalRect(&r);
- SetPort(port);
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenGroupCell
-
- Open one subject window for a cell in a group list window.
-
- Entry: groupWind = pointer to group list window.
- theCell = the cell in the group list window to be opened.
- maxFetch = maximum number of articles to fetch.
-
- Exit: function result = error code.
- *hasArts = true if the group exists, has articles, and the window
- was opened.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenGroupCell (WindowPtr groupWind, Cell theCell, short maxFetch, Boolean *hasArts)
- {
- WindowPtr wind = nil;
- TWindow **groupInfo, **info;
- ListHandle theList;
- TGroup **groupArray, theGroup;
- TSubject **subjectArray = nil;
- short numSubjects = 0;
- Handle subjectStrings = nil;
- CStr255 groupName;
- short cellDataLen, index;
- TGroupWindowKind groupKind;
- Cell childCell;
- CStr255 statusMsg;
- long firstFetched;
- OSErr err = noErr;
- Boolean groupExists;
- GrafPtr port;
-
- GetPort(&port);
-
- *hasArts = true;
-
- /* Check to see if the subject window is already open. Bring it
- to the front if it is. */
-
- if ((wind = FindChild(groupWind, theCell)) != nil) {
- MySelectWindow(wind);
- return noErr;
- }
-
- /* Initialize. */
-
- groupInfo = (TWindow**)GetWRefCon(groupWind);
- groupKind = (**groupInfo).groupKind;
- theList = (**groupInfo).theList;
- groupArray = (**groupInfo).groupArray;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theGroup = (*groupArray)[index];
- strcpy(groupName, *gGroupNames + theGroup.nameOffset);
- if (groupKind == kUserGroup && theGroup.numUnread == 0) goto exit1;
-
- if (groupKind == kUserGroup) (**groupInfo).changed = true;
-
- /* Display the status window. */
-
- if (gPrefs.showAuthors) {
- GetCString(kStrGettingSubjectsAndAuthorsStatusMsg, statusMsg);
- } else {
- GetCString(kStrGetSubjectsStatusMsg, statusMsg);
- }
- strcat(statusMsg, groupName);
- statusMsg[255] = 0;
- err = DisplayStatusMessage(statusMsg);
- if (err != noErr) goto exit2;
-
- /* If we are opening a cell in the full group list window or the new groups
- window, first call GetGroupArticleRange to get the [low,high] article range
- for the group. */
-
- if (groupKind != kUserGroup) {
- err = GetGroupArticleRange(&theGroup, &groupExists);
- if (err != noErr) goto exit2;
- if (!groupExists || theGroup.numUnread == 0) goto exit1;
- }
-
- /* Get the subjects and authors from the server. */
-
- err = GetSubjectsAndAuthorsFromNet(groupName, &theGroup, groupKind, maxFetch,
- &subjectArray, &numSubjects, &subjectStrings, &firstFetched);
- if (err != noErr) goto exit2;
- if (numSubjects == 0) goto exit1;
-
- /* Create the subject window. */
-
- c2pstr(groupName);
- err = MakeNewWindow((StringPtr)groupName, &wind);
- if (err != noErr) goto exit2;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- (**info).subjectArray = subjectArray;
- subjectArray = nil;
- (**info).numSubjects = numSubjects;
- (**info).firstFetched = firstFetched;
- (**info).strings = subjectStrings;
- subjectStrings = nil;
- (**info).parentWindow = groupWind;
- (**info).parentGroup = index;
- (**info).groupNameOffset = theGroup.nameOffset;
-
- /* Build the threads. */
-
- err = BuildThreads(wind);
- if (err != noErr) goto exit2;
-
- /* Finish initializing the new subject window. */
-
- err = AddChild(groupWind, wind);
- if (err != noErr) goto exit2;
- SetPt(&childCell, 0, 0);
- MyLSetSelect(true, childCell, (**info).theList);
- if (!(**info).windPosLocked) {
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit2;
- }
-
- /* For a user group list, update the unread list and the number
- of unread articles counter. */
-
- if (groupKind == kUserGroup) {
- err = UpdateUnreadList(wind);
- if (err != noErr) goto exit2;
- (*groupArray)[index].onlyRedrawCount = true;
- LDraw(theCell, theList);
- (*groupArray)[index].onlyRedrawCount = false;
- }
-
- /* Show the new subject window. */
-
- MyShowWindow(wind);
-
- SetPort(port);
- return noErr;
-
- exit1:
-
- MyDisposeHandle(subjectArray);
- MyDisposeHandle(subjectStrings);
- if (groupKind == kUserGroup) {
- DisposeGroupUnreadList(&theGroup);
- (*groupArray)[index] = theGroup;
- (*groupArray)[index].onlyRedrawCount = true;
- LDraw(theCell, theList);
- (*groupArray)[index].onlyRedrawCount = false;
- }
- *hasArts = false;
- SetPort(port);
- return noErr;
-
- exit2:
-
- if (wind != nil) {
- /* Hack to avoid marking articles read in mark.c/UpdateUnreadList */
- (**info).firstFetched = 0x7fffffff;
- (**info).numSubjectsInList = 0;
- }
- DoClose(wind);
- MyDisposeHandle(subjectArray);
- MyDisposeHandle(subjectStrings);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenSelectedCells
-
- Open all the selected articles in a subject list window.
-
- Entry: wind = pointer to subject list window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr OpenSelectedCells (WindowPtr wind)
- {
- Cell theCell;
- TWindow **info;
- ListHandle theList;
- short *p, *pBegin, numSelected=0, numOpened=0;
- OSErr err = noErr;
- WindowPtr child;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
-
- SetPt(&theCell, 0, (**theList).dataBounds.bottom-1);
- while (theCell.v >= 0) {
- pBegin = (**theList).cellArray;
- p = pBegin + theCell.v;
- while (*p >= 0 && p >= pBegin) p--;
- theCell.v = p - pBegin;
- if (p >= pBegin) {
- err = OpenSubjectCell(wind, theCell, 1, nil, &child);
- if (err != noErr) return err;
- numSelected++;
- if (child != nil) numOpened++;
- }
- theCell.v--;
- }
- if (numOpened < numSelected) {
- if (numSelected == 1) {
- NoteMessageNumber(kStrSelArticleDoesntExist);
- } else {
- if (numOpened == 0) {
- NoteMessageNumber(kStrNoneExist);
- } else {
- NoteMessageNumber(kStrSomeDontExist);
- }
- }
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CancelSubjectCell
-
- Cancel the article corresponding to a cell in a subject list window.
-
- Entry: wind = pointer to subject list window.
- cell = cell to cancel.
- statusMsg = status message, C-format.
-
- Exit: function result = error code.
- *canceled = true if canceled or article does not exist,
- false if user is not owner of article.
- ----------------------------------------------------------------------------*/
-
- static OSErr CancelSubjectCell (WindowPtr wind, Cell theCell, char *statusMsg,
- Boolean *canceled)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short index, cellDataLen;
- long number;
- CStr255 groupName, idStr;
- OSErr err = noErr;
- Handle text = nil;
- Handle groups = nil;
- long length;
- Boolean attachedFile;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- number = (*subjectArray)[index].number;
- strcpy(groupName, *gGroupNames + (**info).groupNameOffset);
-
- err = GetArticle(nil, 0, groupName, number, nil, "HEAD", false, false, &text,
- &length, &attachedFile);
- if (err != noErr) return err;
-
- if (text == nil) {
- *canceled = true;
- return noErr;
- }
-
- if (!UserIsPoster(text)) {
- *canceled = false;
- return noErr;
- }
-
- if (!FindHeaderCString(text, "Message-ID", idStr, sizeof(idStr))) goto exit1;
-
- err = FindHeaderHandle(text, "Newsgroups", &groups);
- if (err != noErr) goto exit2;
- if (groups == nil) goto exit3;
-
- MyDisposeHandle(text);
- text = nil;
-
- err = CancelArticle(idStr, groups, statusMsg);
- if (err != noErr) goto exit2;
-
- *canceled = true;
- MyDisposeHandle(groups);
- return noErr;
-
- exit1:
-
- MyDisposeHandle(text);
- MyDisposeHandle(groups);
- ErrorMessageNumber(kStrNoMsgID);
- return userCanceledErr;
-
- exit2:
-
- MyDisposeHandle(text);
- MyDisposeHandle(groups);
- return err;
-
- exit3:
-
- MyDisposeHandle(text);
- MyDisposeHandle(groups);
- ErrorMessageNumber(kStrNoNewsgroupsHeader);
- return userCanceledErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- EncodedTextBeginLineIsRequired
-
- Determine whether or not an article requires a BinHex or uuencode
- beginning "flag" line for attached binaries.
-
- Entry: subjectArray = handle to subject array.
- index = index in subject array.
-
- Exit: function result = true if flag line required.
- ----------------------------------------------------------------------------*/
-
- Boolean EncodedTextBeginLineIsRequired (TSubject **subjectArray, short index)
- {
- TSubject *s;
-
- s = &(*subjectArray)[index];
- return s->partNum == 0 || s->partNum == 0x7fff ||
- (!s->incomplete && s->threadOrdinal == 1);
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenMessageWindowForOneCell
-
- Open a reply, forward, or redirect window for a cell in a subject list window.
-
- Entry: wind = pointer to subject list window.
- cell = cell in window.
- modifiers = modifiers field from event record.
- func = pointer to function to open one message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr OpenMessageWindowForOneCell (WindowPtr wind, Cell theCell,
- short modifiers, OSErr (*func)(Handle, Handle, long, long, Boolean))
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short index, cellDataLen;
- long number;
- CStr255 groupName;
- OSErr err = noErr;
- Handle text = nil;
- long length;
- Boolean attachedFile, flagReqd;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- number = (*subjectArray)[index].number;
- flagReqd = EncodedTextBeginLineIsRequired(subjectArray, index);
- strcpy(groupName, *gGroupNames + (**info).groupNameOffset);
-
- err = GetArticle(nil, 0, groupName, number, nil, "ARTICLE", true,
- flagReqd, &text, &length, &attachedFile);
- if (err != noErr) return err;
-
- if (text == nil) return noErr;
-
- err = (*func)(text, nil, 0, 0, (modifiers & optionKey) != 0);
-
- MyDisposeHandle(text);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenMessageWindowForAllSelectedCells
-
- Open a reply, forward, or redirect message window for all selected
- cells in a subject window.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
- func = pointer to function to open one message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr OpenMessageWindowForAllSelectedCells (WindowPtr wind,
- short modifiers, OSErr (*func)(Handle, Handle, long, long, Boolean))
- {
- Cell theCell;
- TWindow **info;
- ListHandle theList;
- short *p, *pBegin;
- OSErr err = noErr;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
-
- SetPt(&theCell, 0, (**theList).dataBounds.bottom-1);
- while (theCell.v >= 0) {
- pBegin = (**theList).cellArray;
- p = pBegin + theCell.v;
- while (*p >= 0 && p >= pBegin) p--;
- theCell.v = p - pBegin;
- if (p >= pBegin) {
- err = OpenMessageWindowForOneCell(wind, theCell, modifiers, func);
- if (err != noErr) return err;
- }
- theCell.v--;
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FormFileName
-
- Form the default file name for saving articles.
-
- Entry: wind = pointer to subject window.
- theCell = cell in window.
-
- Exit: function result = error code.
- fileName = default file name.
-
- The file name is formed from the subject of the first selected cell
- which is >= theCell.
- ----------------------------------------------------------------------------*/
-
- static OSErr FormFileName (WindowPtr wind, Cell theCell, Str31 fileName)
- {
- TWindow **info;
- TSubject **subjectArray;
- ListHandle theList;
- Str255 subject;
- long subjectOffset;
- short cellDataLen, index;
- Handle strings;
-
- info = (TWindow**)GetWRefCon(wind);
- subjectArray = (**info).subjectArray;
- theList = (**info).theList;
- strings = (**info).strings;
- if (!LGetSelect(true, &theCell, theList)) return userCanceledErr;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- subjectOffset = (*subjectArray)[index].subjectOffset;
- strcpy((char*)subject, *strings + subjectOffset);
- c2pstr((char*)subject);
- MakeLegalFileName(subject, fileName);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveOneCellToFile
-
- Save a single cell to a file.
-
- Entry: wind = pointer to subject window.
- theCell = cell to save.
- refNum = file ref num.
- statusMsg = status message.
- *artNum = article ordinal within sequence of articles
- being saved (1,2,3,...).
- numArticlestoSave = total number of articles being saved.
- writeSeparator = true to write separator before first saved
- article.
- saveEncodedText = true to save encoded text.
-
- Exit: function result = error code.
- *artNum updated.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveOneCellToFile (WindowPtr wind, Cell theCell, short refNum,
- char *statusMsg, short *artNum, short numArticlesToSave,
- Boolean writeSeparator, Boolean saveEncodedText)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short index, cellDataLen;
- long number;
- CStr255 groupName, msg;
- OSErr err = noErr;
- TAttachedFileKind fileKind;
- char *separator;
- long length;
- Boolean truncateIfAttachedFile, flagReqd;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- strcpy(groupName, *gGroupNames + (**info).groupNameOffset);
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
-
- while (true) {
- if (writeSeparator) {
- separator =
- "\r----------------------------------------------------------------------\r\r";
- length = strlen(separator);
- err = MyFSWriteNoCache(refNum, &length, separator, nil);
- if (err != noErr) return err;
- }
- writeSeparator = true;
- (*artNum)++;
- if (numArticlesToSave == 1) {
- strcpy(msg, statusMsg);
- } else {
- sprintf(msg, statusMsg, *artNum, numArticlesToSave);
- }
- err = DisplayStatusMessage(msg);
- if (err != noErr) return err;
- number = (*subjectArray)[index].number;
- truncateIfAttachedFile = !saveEncodedText;
- flagReqd = EncodedTextBeginLineIsRequired(subjectArray, index);
- err = CopyArticleToFile(groupName, number, nil, "ARTICLE", refNum,
- truncateIfAttachedFile, flagReqd, &fileKind);
- if (err != noErr) return err;
- if ((*subjectArray)[index].collapsed) {
- index = (*subjectArray)[index].nextInThread;
- if (index == -1) break;
- } else {
- break;
- }
- }
- MarkSubjectCellRead(wind, theCell);
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveSelectedArticlesToFile
-
- Save selected articles to a file.
-
- Entry: wind = pointer to subject window.
- fSpec = pointer to file spec.
- scriptTag = script code.
- append = true to append to end of file.
- saveEncodedText = true to save encoded text.
- saveThreadsToSeparateFiles = true to save threads to
- separate files.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveSelectedArticlesToFile (WindowPtr wind, FSSpec *fSpec,
- ScriptCode scriptTag, Boolean append, Boolean saveEncodedText,
- Boolean saveThreadsToSeparateFiles)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short cellDataLen, index;
- short numCells;
- Cell theCell;
- short *p, *pBegin, *pEnd, numArticlesToSave = 0, artNum = 0;
- OSErr err = noErr;
- CStr255 statusMsg;
- short refNum = 0;
- Boolean empty, writeSeparator;
- short threadHeadIndex, prevThreadHeadIndex;
-
- MyICReadSharedPrefs(kICeditorHelper);
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- numCells = (**theList).dataBounds.bottom;
-
- SetPt(&theCell, 0, 0);
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- if ((*subjectArray)[index].collapsed) {
- numArticlesToSave += (*subjectArray)[index].threadLength;
- } else {
- numArticlesToSave++;
- }
- }
- theCell.v++;
- }
-
- if (numArticlesToSave == 0) {
- return noErr;
- } else if (numArticlesToSave == 1) {
- GetCString(kStrGettingAndSavingArticle, statusMsg);
- } else {
- GetCString(kStrGettingAndSavingArticleNofM, statusMsg);
- }
-
- if (!saveThreadsToSeparateFiles) {
- err = OpenDataForkWriteCreateIfMissing(fSpec, gPrefs.savedArtCreator, 'TEXT',
- scriptTag, append, &refNum, &empty);
- if (err != noErr) return err;
- writeSeparator = !empty;
- }
-
- SetPt(&theCell, 0, 0);
- prevThreadHeadIndex = -1;
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- if (saveThreadsToSeparateFiles) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- threadHeadIndex = (*subjectArray)[index].threadHeadIndex;
- if (threadHeadIndex != prevThreadHeadIndex) {
- if (refNum != 0) {
- MyFSClose(refNum, GiveTime);
- refNum = 0;
- err = FormFileName(wind, theCell, fSpec->name);
- if (err != noErr) goto exit;
- err = FileOrFolderExists(fSpec);
- if (err != noErr && err != fnfErr) goto exit;
- if (err == noErr && !append) {
- err = MakeFileNameUnique(fSpec, nil);
- if (err != noErr) goto exit;
- }
- }
- err = OpenDataForkWriteCreateIfMissing(fSpec,
- gPrefs.savedArtCreator, 'TEXT',
- scriptTag, append, &refNum, &empty);
- if (err != noErr) goto exit;
- writeSeparator = !empty;
- prevThreadHeadIndex = threadHeadIndex;
- }
- }
- err = SaveOneCellToFile(wind, theCell, refNum, statusMsg, &artNum,
- numArticlesToSave, writeSeparator, saveEncodedText);
- if (err != noErr) goto exit;
- writeSeparator = true;
- }
- theCell.v++;
- }
-
- DoMarkCommand(wind, true);
-
- exit:
-
- if (refNum != 0) MyFSClose(refNum, GiveTime);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- PrintOneArticle
-
- Print a single article.
-
- Entry: groupName = group name.
- number = article number.
- artNum = pointer to article ordinal within sequence of articles
- being printed (1,2,3,...)
- numArts = number of articles being printed.
- requireEncodedTextBeginLIne = true if BinHex or uuencode text
- must include special "begin" flag line.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr PrintOneArticle (CStr255 groupName, long number,
- short *artNum, short numArts, Boolean flagReqd)
- {
- OSErr err = noErr;
- Handle text = nil;
- long textLength;
- Boolean attachedFile;
- CStr255 subject, from, str;
- CStr255 msg, fmt;
-
- if (numArts == 1) {
- GetCString(kStrGettingAndPrinting, msg);
- } else {
- GetCString(kStrGettingAndPrintingNofM, fmt);
- sprintf(msg, fmt, *artNum, numArts);
- }
- err = DisplayStatusMessage(msg);
- if (err != noErr) return err;
- err = GetArticle(nil, 0, groupName, number, nil, "ARTICLE", true,
- flagReqd, &text, &textLength, &attachedFile);
- if (err != noErr) return err;
- FindHeaderCString(text, "Subject", subject, sizeof(subject));
- if (FindHeaderCString(text, "From", from, sizeof(from))) {
- FormatAuthorName(from);
- sprintf(str, "%.40s, %.100s", from, subject);
- } else {
- strcpy(str, subject);
- }
- err = PrintText(text, 0, textLength, str);
- MyDisposeHandle(text);
- (*artNum)++;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- PrintOneCell
-
- Print a single cell.
-
- Entry: wind = pointer to subject window.
- theCell = cell to print.
- artNum = pointer to article ordinal within sequence of articles
- being printed (1,2,3,...)
- numArts = number of articles being printed.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr PrintOneCell (WindowPtr wind, Cell theCell,
- short *artNum, short numArts)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short index, cellDataLen;
- long number;
- CStr255 groupName;
- OSErr err = noErr;
- Boolean flagReqd;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- strcpy(groupName, *gGroupNames + (**info).groupNameOffset);
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
-
- while (true) {
- number = (*subjectArray)[index].number;
- flagReqd = EncodedTextBeginLineIsRequired(subjectArray, index);
- err = PrintOneArticle(groupName, number, artNum, numArts, flagReqd);
- if (err != noErr) return err;
- if ((*subjectArray)[index].collapsed) {
- index = (*subjectArray)[index].nextInThread;
- if (index == -1) break;
- } else {
- break;
- }
- }
-
- MarkSubjectCellRead(wind, theCell);
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DragSubjectsSendProc
-
- The Drag Manager send proc for dragging subjects to the Finder.
-
- Entry: theType = flavor type = 'SPEC'.
- dragSendRefCon = nil.
- theItemRef = item reference.
- theDragRef = drag reference.
-
- Exit: function result = error code.
- gDragTheFile = file spec to be used to save the articles.
- ----------------------------------------------------------------------------*/
-
- static pascal OSErr DragSubjectsSendProc (FlavorType theType,
- void *dragSendRefCon, ItemReference theItemRef, DragReference theDragRef)
- {
- AEDesc dropLocation;
- OSErr err = noErr;
- Cell theCell = {0, 0};
-
- if (DragTargetWasTrash(theDragRef)) return userCanceledErr;
-
- MyICReadSharedPrefs(kICeditorHelper);
-
- err = GetDropLocation(theDragRef, &dropLocation);
- if (err != noErr) return err;
-
- err = GetDropLocationDirectory(&dropLocation, &gDragTheFile.vRefNum,
- &gDragTheFile.parID);
- if (err != noErr) goto exit;
-
- err = FormFileName(gDragSrcWindow, theCell, gDragTheFile.name);
- if (err != noErr) goto exit;
-
- err = MakeFileNameUnique(&gDragTheFile, nil);
- if (err != noErr) goto exit;
-
- err = FSpCreate(&gDragTheFile, gPrefs.savedArtCreator, 'TEXT', smSystemScript);
- if (err != noErr) goto exit;
-
- err = SetDragItemFlavorData(theDragRef, theItemRef, 'SPEC',
- &gDragTheFile, sizeof(FSSpec), 0);
-
- exit:
-
- AEDisposeDesc(&dropLocation);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SubjectListClickLoop
-
- The click loop routine for subject lists when we have the Drag Manager.
-
- Exit: function result = true if mouse button still down, false
- if mouse button released.
- ----------------------------------------------------------------------------*/
-
- static pascal SubjectListClickLoop (void)
- {
- TWindow **info;
- ListHandle theList;
- OSErr err = noErr;
- DragReference dragRef;
- Boolean haveDragRef = false;
- RgnHandle dragRgn = nil;
- PromiseHFSFlavor promise;
-
- info = (TWindow**)GetWRefCon(gDragSrcWindow);
- theList = (**info).theList;
-
- if (gFirstListClickCall) {
- gFirstListClickCall = false;
- return true;
- }
-
- if (WaitMouseMoved(gCurEvent.where)) {
- gDidDrag = true;
- err = NewDrag(&dragRef);
- if (err != noErr) goto exit;
- MyICReadSharedPrefs(kICeditorHelper);
- haveDragRef = true;
- promise.fileType = 'TEXT';
- promise.fileCreator = gPrefs.savedArtCreator;
- promise.fdFlags = 0;
- promise.promisedFlavor = 'SPEC';
- err = AddDragItemFlavor(dragRef, 1, flavorTypePromiseHFS, &promise,
- sizeof(PromiseHFSFlavor), 0);
- if (err != noErr) goto exit;
- err = AddDragItemFlavor(dragRef, 1, 'SPEC', nil, 0, 0);
- if (err != noErr) goto exit;
- err = SetDragSendProc(dragRef, gDragSubjectsSendProcUPP, nil);
- if (err != noErr) goto exit;
- BuildListSelectedCellsDragRegion(theList, &dragRgn);
- err = TrackDrag(dragRef, &gCurEvent, dragRgn);
- if (err != noErr) goto exit;
- DisposeRgn(dragRgn);
- DisposeDrag(dragRef);
- gDraggedToFinder = true;
- }
-
- return false;
-
- exit:
-
- if (dragRgn != nil) DisposeRgn(dragRgn);
- if (haveDragRef) DisposeDrag(dragRef);
- gClickLoopErr = err;
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyDlgLabelUserItem
-
- A user item procedure to draw the label in the extract binaries
- manually dialog.
-
- Entry: dlg = pointer to dialog.
- item = item number.
- ----------------------------------------------------------------------------*/
-
- static pascal void ExtractBinariesManuallyDlgLabelUserItem (DialogPtr dlg, short item)
- {
- Str255 label;
- Handle itemHandle;
- short itemType;
- Rect box;
- TextStyle savedStyle;
-
- GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
- GetPString(kStrExtractBinariesManuallyDlgLabel, label);
- GetPortTextStyle(&savedStyle);
- TextFont(systemFont);
- TextSize(12);
- TETextBox(label+1, label[0], &box, teForceLeft);
- SetPortTextStyle(&savedStyle);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyDlgListUserItem
-
- A user item procedure to draw the list in the extract binaries
- manually dialog.
-
- Entry: dlg = pointer to dialog.
- item = item number.
- ----------------------------------------------------------------------------*/
-
- static pascal void ExtractBinariesManuallyDlgListUserItem (DialogPtr dlg, short item)
- {
- Handle itemHandle;
- short itemType;
- Rect box;
-
- GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
- FrameRect(&box);
- LUpdate(dlg->visRgn, gExtractBinariesManuallyList);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyHandleTracking
-
- Drag Manager tracking handler for the extract binaries manually
- dialog.
-
- Entry: message = tracking message from Drag Manager.
- wind = pointer to dialog.
- handlerRefCon = reference constant (nil).
- theDrag = drag reference.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static pascal OSErr ExtractBinariesManuallyHandleTracking (DragTrackingMessage message,
- WindowPtr wind, void *handlerRefCon, DragReference theDrag)
- {
- Rect rView, visible, dataBounds, contentRect;
- Point where;
- Boolean inContentRect;
- short scrollDelta, newDestRow;
- static short prevScrollDelta;
- static long scrollTickCount;
-
- rView = (**gExtractBinariesManuallyList).rView;
- visible = (**gExtractBinariesManuallyList).visible;
- dataBounds = (**gExtractBinariesManuallyList).dataBounds;
- contentRect = rView;
- contentRect.top = 0;
- contentRect.bottom = wind->portRect.bottom;
-
- switch (message) {
-
- case dragTrackingEnterHandler:
-
- break;
-
- case dragTrackingEnterWindow:
-
- gDragDestRow = -1;
- prevScrollDelta = 0;
- break;
-
- case dragTrackingInWindow:
-
- GetDragMouse(theDrag, &where, nil);
- GlobalToLocal(&where);
- inContentRect = PtInRect(where, &contentRect);
- if (inContentRect) {
- scrollDelta = 0;
- if (gDragDestRow >= 0) {
- if (where.v < rView.top && visible.top > 0) {
- scrollDelta = -1;
- } else if (where.v > rView.bottom &&
- visible.bottom < dataBounds.bottom)
- {
- scrollDelta = +1;
- }
- }
- if (scrollDelta == prevScrollDelta) {
- if (scrollDelta != 0 && TickCount() - scrollTickCount < 10)
- scrollDelta = 0;
- } else {
- prevScrollDelta = scrollDelta;
- scrollDelta = 0;
- scrollTickCount = TickCount();
- }
- if (scrollDelta != 0) {
- DrawListDividingLine(gExtractBinariesManuallyList, gDragDestRow);
- gDragDestRow = -1;
- MyLScroll(scrollDelta, gExtractBinariesManuallyList);
- }
- newDestRow = ListDestinationRow(gExtractBinariesManuallyList, where);
- if (newDestRow != gDragDestRow) {
- if (gDragDestRow >= 0)
- DrawListDividingLine(gExtractBinariesManuallyList, gDragDestRow);
- gDragDestRow = newDestRow;
- DrawListDividingLine(gExtractBinariesManuallyList, gDragDestRow);
- }
- } else {
- if (gDragDestRow >= 0) {
- DrawListDividingLine(gExtractBinariesManuallyList, gDragDestRow);
- gDragDestRow = -1;
- }
- prevScrollDelta = 0;
- }
- break;
-
- case dragTrackingLeaveWindow:
-
- if (gDragDestRow >= 0)
- DrawListDividingLine(gExtractBinariesManuallyList, gDragDestRow);
- gDragDestRow = -1;
- prevScrollDelta = 0;
- break;
-
- case dragTrackingLeaveHandler:
-
- break;
-
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyHandleReceive
-
- Drag Manager receive handler for the extract binaries manually
- dialog.
-
- Entry: wind = pointer to dialog.
- handlerRefCon = reference constant (nil).
- theDrag = drag reference.
-
- Exit: function result = error code.
-
- Note: No user interaction or network transactions are permitted in
- this function.
- ----------------------------------------------------------------------------*/
-
- static pascal OSErr ExtractBinariesManuallyHandleReceive (WindowPtr wind,
- void *handlerRefCon, DragReference theDrag)
- {
- Boolean changed;
-
- if (gDragDestRow == -1) return dragNotAcceptedErr;
- MoveSelectedListCells(gExtractBinariesManuallyList, gDragDestRow, &changed);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyClickLoop
-
- The click loop routine for the extract binaries manually dialog list
- when we have the Drag Manager. It initiates subject drags.
-
- Exit: function result = true if mouse button still down, false
- if mouse button released.
- ----------------------------------------------------------------------------*/
-
- static Boolean ExtractBinariesManuallyClickLoop (void)
- {
- OSErr err = noErr;
- DragReference dragRef;
- Boolean haveDragRef = false;
- RgnHandle dragRgn = nil;
-
- if (gFirstListClickCall) {
- gFirstListClickCall = false;
- return true;
- }
-
- if (WaitMouseMoved(gCurEvent.where)) {
- err = NewDrag(&dragRef);
- if (err != noErr) goto exit;
- haveDragRef = true;
- err = AddDragItemFlavor(dragRef, 1, kNewsWatcherSignature,
- nil, 0, flavorSenderOnly);
- if (err != noErr) goto exit;
- BuildListSelectedCellsDragRegion(gExtractBinariesManuallyList, &dragRgn);
- gDragDestRow = -1;
- err = TrackDrag(dragRef, &gCurEvent, dragRgn);
- if (err != noErr) goto exit;
- DisposeRgn(dragRgn);
- DisposeDrag(dragRef);
- }
-
- return false;
-
- exit:
-
- if (dragRgn != nil) DisposeRgn(dragRgn);
- if (haveDragRef) DisposeDrag(dragRef);
- gClickLoopErr = err;
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExtractBinariesManuallyDialogFilter
-
- Extract binaries manually dialog filter.
-
- Entry: dlg = pointer to dialog.
- ev = pointer to event record.
-
- Exit: function result = true if event handled and item hit.
- *itemHit = item number of item hit.
- ev = pointer to possibly modified event record.
- ----------------------------------------------------------------------------*/
-
- static pascal Boolean ExtractBinariesManuallyDialogFilter (DialogPtr dlg,
- EventRecord *ev, short *itemHit)
- {
- short itemType;
- Handle itemHandle;
- Rect box;
- Point where;
- Boolean shift, command;
-
- if (ev->what == mouseDown) {
- GetDialogItem(dlg, kExtractBinariesManuallyListItem, &itemType, &itemHandle, &box);
- where = ev->where;
- GlobalToLocal(&where);
- if (PtInRect(where, &box)) {
- shift = (ev->modifiers & shiftKey) != 0;
- command = (ev->modifiers & cmdKey) != 0;
- if (!shift && !command) {
- if (gHaveDragMgr) {
- gFirstListClickCall = true;
- gClickLoopErr = noErr;
- gDragSrcWindow = dlg;
- gCurEvent = *ev;
- (**gExtractBinariesManuallyList).lClickLoop =
- gExtractBinariesManuallyClickLoopUPP;
- MyLClick(where, ev->modifiers, gExtractBinariesManuallyList);
- } else {
- OldBeginListClick(gExtractBinariesManuallyList);
- (**gExtractBinariesManuallyList).lClickLoop =
- gOldListClickLoopUPP;
- MyLClick(where, ev->modifiers, gExtractBinariesManuallyList);
- OldEndListClick();
- }
- } else {
- (**gExtractBinariesManuallyList).lClickLoop = nil;
- MyLClick(where, ev->modifiers, gExtractBinariesManuallyList);
- }
- return false;
- }
- }
- return DialogFilter(dlg, ev, itemHit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Find
-
- Search a subject window for a pattern.
-
- Entry: wind = pointer to subject window.
- theCell = first cell to search.
- again = true if "Find Again", in which case the search starts
- at the article *following* the first cell to search.
- gFindPattern = pattern.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Find (WindowPtr wind, Cell theCell, Boolean again)
- {
- TWindow **info;
- TSubject **subjectArray;
- TSubject theSubject;
- ListHandle theList;
- Handle strings;
- short index, cellDataLen, numCells, autoExpandedThread;
- unsigned long tickLongTime;
- Boolean longTime = false;
- OSErr err = noErr;
- char state;
- CStr255 str;
- Boolean authorMatch, subjectMatch;
- Cell autoExpandedCell;
-
- info = (TWindow**)GetWRefCon(wind);
- subjectArray = (**info).subjectArray;
- theList = (**info).theList;
- strings = (**info).strings;
- numCells = (**theList).dataBounds.bottom;
- tickLongTime = TickCount() + 30;
-
- state = MyHGetState(strings);
- MyHLock(strings);
-
- while (theCell.v < numCells) {
-
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
-
- if (again) {
- if (theSubject.collapsed) {
- index = theSubject.nextInThread;
- } else {
- index = -1;
- }
- again = false;
- }
-
- while (index != -1) {
-
- theSubject = (*subjectArray)[index];
-
- if (theSubject.authorOffset == -1) {
- authorMatch = false;
- } else {
- strcpy(str, *strings + theSubject.authorOffset);
- FormatAuthorName(str);
- authorMatch = MyIsASubstring(str, gFindPattern);
- }
-
- subjectMatch = theSubject.threadOrdinal == 1 &&
- MyIsASubstring(*strings + theSubject.subjectOffset, gFindPattern);
-
- if (authorMatch || subjectMatch) {
- MyHSetState(strings, state);
- autoExpandedThread = (**info).autoExpandedThread;
- if (autoExpandedThread != -1 &&
- autoExpandedThread != theSubject.threadHeadIndex &&
- !(*subjectArray)[autoExpandedThread].collapsed &&
- FindParentCell(wind, autoExpandedThread, &autoExpandedCell))
- {
- ExpandCollapseThread(wind, autoExpandedCell);
- (**info).autoExpandedThread = -1;
- if (autoExpandedCell.v < theCell.v)
- theCell.v -= (*subjectArray)[autoExpandedThread].threadLength - 1;
- err = RezoomSubjectWindow(wind, false);
- if (err != noErr) return err;
- }
- if (theSubject.collapsed && theSubject.threadOrdinal > 1) {
- ExpandCollapseThread(wind, theCell);
- (**info).autoExpandedThread = theSubject.threadHeadIndex;
- theCell.v += theSubject.threadOrdinal - 1;
- err = RezoomSubjectWindow(wind, true);
- if (err != noErr) return err;
- }
- SelectSingleListItem(theList, theCell);
- MyLScrollCenter(theCell, theList);
- return noErr;
- }
-
- if (!theSubject.collapsed) break;
- index = theSubject.nextInThread;
- }
-
- theCell.v++;
- if ((theCell.v & 0xf) == 0) {
- if (!longTime && TickCount() > tickLongTime) longTime = true;
- if (longTime) {
- err = GiveTime(false);
- if (err != noErr) {
- MyHSetState(strings, state);
- return err;
- }
- }
- }
- }
-
- MyHSetState(strings, state);
- SysBeep(0);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSave
-
- Handle the "Save" command.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoSave (WindowPtr wind, short modifiers)
- {
- Str31 fileName;
- FSSpec fSpec;
- ScriptCode scriptTag;
- Boolean append = false;
- OSErr err = noErr;
- Boolean saveEncodedText, saveThreadsToSeparateFiles;
- Cell theCell = {0, 0};
-
- saveEncodedText = gPrefs.saveEncodedText;
- saveThreadsToSeparateFiles = gPrefs.saveThreadsToSeparateFiles;
- err = FormFileName(wind, theCell, fileName);
- if (err != noErr) return err;
- if (gPrefs.savedArtDefaultFolder && (modifiers & optionKey) == 0) {
- err = CheckArticleFileExists(fileName, &fSpec, &scriptTag,
- &append, &saveEncodedText, &saveThreadsToSeparateFiles);
- if (err != noErr) return err;
- } else {
- err = PresentStandardArticleSaveFileDialog(fileName, &fSpec, &scriptTag,
- &saveEncodedText, &saveThreadsToSeparateFiles);
- if (err != noErr) return err;
- }
- return SaveSelectedArticlesToFile(wind, &fSpec, scriptTag, append,
- saveEncodedText, saveThreadsToSeparateFiles);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSaveAs
-
- Handle the "SaveAs" command.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoSaveAs (WindowPtr wind)
- {
- Str31 fileName;
- FSSpec fSpec;
- ScriptCode scriptTag;
- OSErr err = noErr;
- Boolean saveEncodedText, saveThreadsToSeparateFiles;
- Cell theCell = {0, 0};
-
- saveEncodedText = gPrefs.saveEncodedText;
- saveThreadsToSeparateFiles = gPrefs.saveThreadsToSeparateFiles;
- FormFileName(wind, theCell, fileName);
- err = PresentStandardArticleSaveFileDialog(fileName, &fSpec, &scriptTag,
- &saveEncodedText, &saveThreadsToSeparateFiles);
- if (err != noErr) return err;
- return SaveSelectedArticlesToFile(wind, &fSpec, scriptTag, false,
- saveEncodedText, saveThreadsToSeparateFiles);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoAppend
-
- Handle the "Append" command.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoAppend (WindowPtr wind)
- {
- FSSpec fSpec;
- OSErr err = noErr;
- Boolean saveEncodedText;
-
- saveEncodedText = gPrefs.saveEncodedText;
- err = PresentStandardArticleGetFileDialog(&fSpec, &saveEncodedText);
- if (err != noErr) return err;
- return SaveSelectedArticlesToFile(wind, &fSpec, smSystemScript, true,
- saveEncodedText, false);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoPrint
-
- Handle the "Print" command.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoPrint (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short numCells;
- Cell theCell;
- short *p, *pBegin, *pEnd;
- OSErr err = noErr;
- short artNum, numArts;
- short cellDataLen, index;
-
- err = StartPrint();
- if (err != noErr) return err;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
- numCells = (**theList).dataBounds.bottom;
- subjectArray = (**info).subjectArray;
-
- SetPt(&theCell, 0, 0);
- numArts = 0;
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- if ((*subjectArray)[index].collapsed) {
- numArts += (*subjectArray)[index].threadLength;
- } else {
- numArts++;
- }
- }
- theCell.v++;
- }
-
- artNum = 1;
- SetPt(&theCell, 0, 0);
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- err = PrintOneCell(wind, theCell, &artNum, numArts);
- if (err != noErr) goto exit;
- }
- theCell.v++;
- }
-
- exit:
-
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSelectAll
-
- Handle the "Select All" command for a subject window.
-
- Entry: wind = pointer to subject window.
- ----------------------------------------------------------------------------*/
-
- static void DoSelectAll (WindowPtr wind)
- {
- TWindow **info;
-
- info = (TWindow**)GetWRefCon(wind);
- SelectOrDeselectAllListItems((**info).theList, true);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoDeselectAll
-
- Handle the "Deselect All" command for a subject window.
-
- Entry: wind = pointer to subject window.
- ----------------------------------------------------------------------------*/
-
- static void DoDeselectAll (WindowPtr wind)
- {
- TWindow **info;
-
- info = (TWindow**)GetWRefCon(wind);
- SelectOrDeselectAllListItems((**info).theList, false);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoFind
-
- Handle the "Find" command for a subject window.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoFind (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- Cell theCell;
- OSErr err = noErr;
-
- err = DoFindDialog();
- if (err != noErr) return err;
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- SetPt(&theCell, 0, 0);
- if (!gPrefs.startFindAtBeginning) LGetSelect(true, &theCell, theList);
- return Find(wind, theCell, false);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoFindAgain
-
- Handle the "Find Again" command for a subject window.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoFindAgain (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- Cell theCell;
-
- info = (TWindow**)GetWRefCon(wind);
-
- theList = (**info).theList;
- SetPt(&theCell, 0, 0);
- LGetSelect(true, &theCell, theList);
- return Find(wind, theCell, true);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoReply
-
- Handle the "Reply" command.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoReply (WindowPtr wind, short modifiers)
- {
- return OpenMessageWindowForAllSelectedCells(wind, modifiers, OpenReplyWindow);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoForward
-
- Handle the "Forward" command.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoForward (WindowPtr wind, short modifiers)
- {
- return OpenMessageWindowForAllSelectedCells(wind, modifiers, OpenForwardWindow);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoRedirect
-
- Handle the "Redirect" command.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoRedirect (WindowPtr wind, short modifiers)
- {
- return OpenMessageWindowForAllSelectedCells(wind, modifiers, OpenRedirectWindow);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoExtractBinaries
-
- Handle the "Extract Binaries" command for a subject window.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoExtractBinaries (WindowPtr wind, short modifiers)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short cellDataLen, index;
- short numCells, partNum;
- Cell theCell;
- short *p, *pBegin, *pEnd, numArts = 0, artNum = 0;
- OSErr err = noErr;
- short prevThreadHeadIndex = -1, threadHeadIndex;
- short numArtsWithoutAttachedFiles = 0, numIncomplete = 0, numArtsNotOnServer = 0;
- Boolean incomplete;
- TAttachedFileKind fileKind;
- CStr255 fmt, msg;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- numCells = (**theList).dataBounds.bottom;
-
- SetPt(&theCell, 0, 0);
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- incomplete = (*subjectArray)[index].incomplete;
- partNum = (*subjectArray)[index].partNum;
- threadHeadIndex = (*subjectArray)[index].threadHeadIndex;
- if (incomplete) {
- numIncomplete++;
- } else if (partNum == 0x7fff) {
- numArts++;
- } else if (threadHeadIndex != prevThreadHeadIndex) {
- prevThreadHeadIndex = threadHeadIndex;
- numArts++;
- }
- }
- theCell.v++;
- }
-
- if (numArts == 0) {
- if (numIncomplete > 0) {
- if (numIncomplete == 1) {
- NoteMessageNumber(kStrDecodePartsMissing);
- } else {
- NoteMessageNumber(kStrAllSelectedArtsHaveMissingParts);
- }
- }
- return noErr;
- }
-
- SetPt(&theCell, 0, 0);
- prevThreadHeadIndex = -1;
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- threadHeadIndex = (*subjectArray)[index].threadHeadIndex;
- incomplete = (*subjectArray)[index].incomplete;
- partNum = (*subjectArray)[index].partNum;
- threadHeadIndex = (*subjectArray)[index].threadHeadIndex;
- if (!incomplete && (partNum == 0x7fff || threadHeadIndex != prevThreadHeadIndex)) {
- artNum++;
- err = ExtractBinaries(wind, index, artNum, numArts, modifiers, &fileKind);
- if (err != noErr) return err;
- if (fileKind == kNoAttachedFile) numArtsWithoutAttachedFiles++;
- if (fileKind == kArtNotOnServer) numArtsNotOnServer++;
- if (partNum != 0x7fff) prevThreadHeadIndex = threadHeadIndex;
- }
- }
- theCell.v++;
- }
-
- if (numArtsWithoutAttachedFiles > 0) {
- if (numArts == 1) {
- NoteMessageNumber(kStrArtHasNoAttachedFile);
- } else if (numArtsWithoutAttachedFiles == 1) {
- NoteMessageNumber(kStrOneArtSkippedNoAttachedFile);
- } else {
- GetCString(kStrNArtsSkippedNoAttachedFile, fmt);
- sprintf(msg, fmt, numArtsWithoutAttachedFiles);
- NoteMessage(msg);
- }
- }
-
- if (numArtsNotOnServer > 0) {
- if (numArts == 1) {
- NoteMessageNumber(kStrArtNotOnServer);
- } else if (numArtsNotOnServer == 1) {
- NoteMessageNumber(kStrOneArtSkippedNotOnServer);
- } else {
- GetCString(kStrNArtsSkippedNotOnServer, fmt);
- sprintf(msg, fmt, numArtsNotOnServer);
- NoteMessage(msg);
- }
- }
-
- if (numIncomplete == 1) {
- NoteMessageNumber(kStrOneArtSkippedMissingParts);
- } else if (numIncomplete > 1) {
- GetCString(kStrNArtsSkippedMissingParts, fmt);
- sprintf(msg, fmt, numIncomplete);
- NoteMessage(msg);
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoExtractBinariesManually
-
- Handle the "Extract Binaries Manually" command for a subject window.
-
- Entry: wind = pointer to subject window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoExtractBinariesManually (WindowPtr wind, short modifiers)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- short numCells;
- short cellDataLen, index;
- short *p, *pBegin, *pEnd, numSelected = 0;
- Handle strings;
- OSErr err = noErr;
- DialogPtr dlg = nil;
- short item, fontNum, itemType, lineHeight, listHeight;
- Handle itemHandle;
- Rect rView;
- Rect dataBounds = {0, 0, 0, 1};
- Point cSize = {0, 0};
- CStr255 subject, str;
- Cell cella, cellb;
- long number;
- long **artList = nil;
- short artNum;
- Str31 fileName;
- FSSpec fSpec;
- ScriptCode scriptTag;
- CStr255 statusMsg, statusMsgFormat;
- CStr255 groupName;
- TAttachedFileKind fileKind = kNoAttachedFile, partKind;
- long totalCellDataLength = 0;
- short refNum = 0;
- Boolean empty;
-
- gExtractBinariesManuallyList = nil;
- *fSpec.name = 0;
-
- if (!MemoryAvailable(40000)) {
- err = memFullErr;
- goto exit;
- }
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- strings = (**info).strings;
- numCells = (**theList).dataBounds.bottom;
- strcpy(groupName, *gGroupNames + (**info).groupNameOffset);
-
- err = MyGetNewDialog(kExtractBinariesManuallyDlg, ok, cancel, &dlg);
- if (err != noErr) return err;
- DlgSetUserItem(dlg, kExtractBinariesManuallyLabelItem,
- gExtractBinariesManuallyDlgLabelUserItemUPP);
- DlgSetUserItem(dlg, kExtractBinariesManuallyListItem,
- gExtractBinariesManuallyDlgListUserItemUPP);
-
- if (gHaveDragMgr) {
- err = InstallTrackingHandler(gExtractBinariesManuallyHandleTrackingUPP,
- dlg, nil);
- if (err != noErr) goto exit;
- err = InstallReceiveHandler(gExtractBinariesManuallyHandleReceiveUPP,
- dlg, nil);
- if (err != noErr) goto exit;
- }
-
- SetPort(dlg);
-
- GetFontNumber("\pMonaco", &fontNum);
- TextFont(fontNum);
- TextSize(9);
-
- GetDialogItem(dlg, kExtractBinariesManuallyListItem, &itemType, &itemHandle, &rView);
- InsetRect(&rView, 1, 1);
- rView.right -= 15;
- lineHeight = GetFontLineHeight(dlg);
- listHeight = rView.bottom - rView.top;
- listHeight = listHeight/lineHeight*lineHeight;
- rView.bottom = rView.top + listHeight;
- gExtractBinariesManuallyList = LNew(&rView, &dataBounds, cSize, 0,
- dlg, true, false, false, true);
- (**gExtractBinariesManuallyList).indent.h = 4;
- (**gExtractBinariesManuallyList).selFlags |= lNoNilHilite;
- rView.right += 15;
- InsetRect(&rView, -1, -1);
- SetDialogItem(dlg, kExtractBinariesManuallyListItem, itemType, itemHandle, &rView);
-
- numSelected = NumListItemsSelected(theList);
- LAddRow(numSelected, 0, gExtractBinariesManuallyList);
-
- SetPt(&cella, 0, 0);
- SetPt(&cellb, 0, 0);
- while (cella.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + cella.v;
- while (*p >= 0 && p < pEnd) p++;
- cella.v = p - pBegin;
- if (p < pEnd) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, cella, theList);
- strcpy(subject, *strings + (*subjectArray)[index].subjectOffset);
- sprintf(str, "%ld - %.240s", (*subjectArray)[index].number, subject);
- totalCellDataLength += strlen(str);
- if (totalCellDataLength > 0x7fff) {
- ErrorMessageNumber(kStrExtractBinariesManuallyTooMuchCellData);
- goto exit;
- }
- LSetCell(str, strlen(str), cellb, gExtractBinariesManuallyList);
- cellb.v++;
- }
- cella.v++;
- }
-
- MyModalDialog(dlg, gExtractBinariesManuallyDialogFilterUPP, &item);
-
- if (item == ok) {
- err = MyNewHandle(numSelected * sizeof(long), &artList);
- if (err != noErr) goto exit;
- SetPt(&cellb, 0, 0);
- while (cellb.v < numSelected) {
- cellDataLen = 256;
- LGetCell(str, &cellDataLen, cellb, gExtractBinariesManuallyList);
- str[cellDataLen] = 0;
- number = atol(str);
- (*artList)[cellb.v] = number;
- cellb.v++;
- }
- }
-
- LDispose(gExtractBinariesManuallyList);
- gExtractBinariesManuallyList = nil;
-
- if (gHaveDragMgr) {
- RemoveTrackingHandler(gExtractBinariesManuallyHandleTrackingUPP, dlg);
- RemoveReceiveHandler(gExtractBinariesManuallyHandleReceiveUPP, dlg);
- }
-
- err = DoClose(dlg);
- if (err != noErr) return err;
- dlg = nil;
- if (item == cancel) return userCanceledErr;
-
- GetPString(kStrTempFileName, fileName);
-
- if (gPrefs.savedBinDefaultFolder && (modifiers & optionKey) == 0) {
- err = CheckDownloadFileExists(fileName, &fSpec, &scriptTag);
- if (err != noErr) goto exit;
- } else {
- err = PresentStandardDownloadSaveFileDialog(fileName, &fSpec, &scriptTag);
- if (err != noErr) goto exit;
- }
-
- GetCString(kStrGettingAndSavingPartNofM, statusMsgFormat);
-
- MyICReadSharedPrefs(kICeditorHelper);
-
- err = OpenDataForkWriteCreateIfMissing(&fSpec, gPrefs.savedArtCreator, 'TEXT',
- scriptTag, false, &refNum, &empty);
- if (err != noErr) return err;
-
- for (artNum = 0; artNum < numSelected; artNum++) {
- sprintf(statusMsg, statusMsgFormat, artNum+1, numSelected);
- err = DisplayStatusMessage(statusMsg);
- if (err != noErr) goto exit;
- number = (*artList)[artNum];
- err = CopyArticleToFile(groupName, number, nil, "ARTICLE", refNum,
- false, false, &partKind);
- if (err != noErr) goto exit;
- if (partKind == kArtNotOnServer) {
- fileKind = kArtNotOnServer;
- break;
- } else if (fileKind == kNoAttachedFile) {
- fileKind = partKind;
- }
- }
-
- MyFSClose(refNum, GiveTime);
-
- MyDisposeHandle(artList);
-
- if (fileKind == kNoAttachedFile) {
- FSpDelete(&fSpec);
- NoteMessageNumber(kStrArtHasNoAttachedFile);
- } else if (fileKind == kArtNotOnServer) {
- FSpDelete(&fSpec);
- NoteMessageNumber(kStrArtNotOnServer);
- } else {
- err = RunDecodeHelperProgram(&fSpec, fileKind);
- *fSpec.name = 0;
- if (err != noErr) goto exit;
- DoMarkCommand(wind, true);
- }
-
- return noErr;
-
- exit:
-
- if (gExtractBinariesManuallyList != nil) LDispose(gExtractBinariesManuallyList);
- gExtractBinariesManuallyList = nil;
- if (dlg != nil) {
- RemoveTrackingHandler(gExtractBinariesManuallyHandleTrackingUPP, dlg);
- RemoveReceiveHandler(gExtractBinariesManuallyHandleReceiveUPP, dlg);
- DoClose(dlg);
- }
- MyDisposeHandle(artList);
- if (refNum != 0) MyFSClose(refNum, GiveTime);
- if (*fSpec.name != 0) FSpDelete(&fSpec);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoCancelArticle
-
- Handle the "Cancel Article" command for a subject window.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoCancelArticle (WindowPtr wind)
- {
- Cell theCell;
- TWindow **info;
- ListHandle theList;
- short *p, *pEnd, *pBegin;
- short numSelected=0, numCanceled=0, i = 0, numCells;
- OSErr err = noErr;
- Boolean canceled;
- CStr255 msg, fmt;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
- numCells = (**theList).dataBounds.bottom;
-
- numSelected = NumListItemsSelected(theList);
- if (numSelected == 0) return noErr;
- if (numSelected == 1) {
- GetCString(kStrCancelingStatusMsg, msg);
- } else {
- GetCString(kStrCancelingNofMStatusMsg, fmt);
- }
-
- SetPt(&theCell, 0, 0);
- while (theCell.v < numCells) {
- pBegin = (**theList).cellArray;
- pEnd = pBegin + numCells;
- p = pBegin + theCell.v;
- while (*p >= 0 && p < pEnd) p++;
- theCell.v = p - pBegin;
- if (p < pEnd) {
- if (numSelected != 1) {
- i++;
- sprintf(msg, fmt, i, numSelected);
- }
- err = DisplayStatusMessage(msg);
- if (err != noErr) return err;
- err = CancelSubjectCell(wind, theCell, msg, &canceled);
- if (err != noErr) return err;
- if (canceled) numCanceled++;
- }
- theCell.v++;
- }
- if (numCanceled < numSelected) {
- if (numSelected == 1) {
- ErrorMessageNumber(kStrNotCanceled);
- } else {
- if (numCanceled == 0) {
- ErrorMessageNumber(kStrNoneCanceled);
- } else if (numSelected - numCanceled == 1) {
- ErrorMessageNumber(kStrOneNotCanceled);
- } else {
- GetCString(kStrNNotCanceled, fmt);
- sprintf(msg, fmt, numSelected - numCanceled);
- ErrorMessage(msg);
- }
- }
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Activate
-
- Handle an activate event for a subject window.
-
- Entry: wind = pointer to subject window.
- act = true to activate, false to deactivate
- ----------------------------------------------------------------------------*/
-
- static void Activate (WindowPtr wind, Boolean act)
- {
- TWindow **info;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- MyLActivate(act, (**info).theList);
- r = wind->portRect;
- r.top = r.bottom - 15;
- r.left = r.right - 15;
- InvalRect(&r);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Update
-
- Handle an update event for a subject window.
-
- Entry: wind = pointer to subject window.
- ----------------------------------------------------------------------------*/
-
- static void Update (WindowPtr wind)
- {
- TWindow **info;
- short panelHeight, windWidth, windHeight, numSubjects, numSubjectsInList;
- short numUnread, i;
- TSubject **subjectArray, *pSubject;
- Rect r;
- FontInfo fontInfo;
- CStr255 str, fmt;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- GetFontInfo(&fontInfo);
- windWidth = wind->portRect.right;
- windHeight = wind->portRect.bottom;
-
- r = wind->portRect;
- r.top += panelHeight;
- ClipRect(&r);
- DrawGrowIcon(wind);
- ClipRect(&wind->portRect);
-
- MoveTo(0, panelHeight-3);
- LineTo(windWidth, panelHeight-3);
- MoveTo(0, panelHeight-1);
- LineTo(windWidth, panelHeight-1);
-
- numSubjects = (**info).numSubjects;
- numSubjectsInList = (**info).numSubjectsInList;
- numUnread = 0;
- subjectArray = (**info).subjectArray;
- for (i = 0, pSubject = *subjectArray; i < numSubjects; i++, pSubject++) {
- if (!pSubject->read && pSubject->inList) numUnread++;
- }
- if (numSubjectsInList == 1) {
- GetCString(kStrOneArt, fmt);
- sprintf(str, fmt, numUnread);
- } else {
- GetCString(kStrNArts, fmt);
- sprintf(str, fmt, numSubjectsInList, numUnread);
- }
- c2pstr(str);
- TruncString(windWidth - 20, (StringPtr)str, smTruncEnd);
- MoveTo(10, fontInfo.ascent + 3);
- DrawString((StringPtr)str);
-
- LUpdate(wind->visRgn, (**info).theList);
-
- DrawPadlockIcon(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Mouse
-
- Handle a mouse down event in the content area of a subject window.
-
- Entry: wind = pointer to subject window.
- where = location of mouse down in local coords.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Mouse (WindowPtr wind, Point where, short modifiers)
- {
- TWindow **info;
- ListHandle theList;
- Boolean triangleClicked, shift, command, doubleClick;
- OSErr err = noErr;
- Rect rView;
-
- info = (TWindow**) GetWRefCon(wind);
- theList = (**info).theList;
-
- shift = (modifiers & shiftKey) != 0;
- command = (modifiers & cmdKey) != 0;
-
- if (where.v < (**info).panelHeight) {
- SelectOrDeselectAllListItems(theList, false);
- return noErr;
- }
-
- err = TriangleClick(wind, where, &triangleClicked);
- if (err != noErr) return err;
- if (triangleClicked) return noErr;
-
- if (HandlePadlockClick(wind, where, &gPrefs.subjectWindPosLocked,
- &gPrefs.subjectWindLocn)) return noErr;
-
- rView = (**theList).rView;
- if (where.v <= rView.top || where.v >= rView.bottom) return noErr;
- if (where.v >= rView.bottom - 1) where.v = rView.bottom - 2;
-
- if (gHaveDragMgr && !shift && !command && PtInListCell(where, theList)) {
-
- gDragSrcWindow = wind;
- gFirstListClickCall = true;
- gClickLoopErr = noErr;
- gDraggedToFinder = false;
- (**theList).lClickLoop = gSubjectListClickLoopUPP;
- gDidDrag = false;
- doubleClick = MyLClickPossiblyInactive(where, modifiers, theList);
- KillBalloon();
- if (doubleClick && !gDidDrag) {
- err = OpenSelectedCells(wind);
- if (err != noErr) return err;
- } else {
- if (gClickLoopErr != noErr) return gClickLoopErr;
- if (gDraggedToFinder) {
- err = SaveSelectedArticlesToFile(wind, &gDragTheFile, smSystemScript, false,
- gPrefs.saveEncodedText, gPrefs.saveThreadsToSeparateFiles);
- if (err != noErr) return err;
- }
- }
-
- } else {
-
- (**theList).lClickLoop = nil;
- if (MyLClickPossiblyInactive(where, modifiers, theList) && !shift && !command) {
- err = OpenSelectedCells(wind);
- if (err != noErr) return err;
- }
- KillBalloon();
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Draggable
-
- Determine whether a mouse down event is on a draggable object in a
- subject window.
-
- Entry: wind = pointer to subject window.
- where = location of mouse down event, in local coordinates.
- modifiers = modifiers field from event record.
-
- Exit: function result = true if object is draggable.
- ----------------------------------------------------------------------------*/
-
- static Boolean Draggable (WindowPtr wind, Point where, short modifiers)
- {
- TWindow **info;
- ListHandle theList;
-
- if ((modifiers & shiftKey) != 0) return false;
- if ((modifiers & cmdKey) != 0) return false;
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- return PtInListCell(where, theList);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Key
-
- Handle a key down event for a subject window.
-
- Entry: wind = pointer to subject window.
- theChar = ASCII code of key.
- theKey = keyboard code of key.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Key (WindowPtr wind, unsigned char theChar, unsigned char theKey,
- short modifiers)
- {
- OSErr err = noErr;
- Cell scrollIntoView;
- TWindow **info;
- ListHandle theList;
- TKeypadKey keypadKey;
- Boolean command, isArrow;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- command = (modifiers & cmdKey) != 0;
- isArrow = IsArrowKey(theChar);
-
- if (command && !isArrow) {
- SysBeep(0);
- return noErr;
- }
-
- if (command && (theChar == leftArrow || theChar == rightArrow))
- return ExpandCollapseKey(wind, theChar);
-
- if (gPrefs.keypadShortcuts && IsKeypadKey(theChar, theKey, &keypadKey)) {
- switch (keypadKey) {
- case kKeypadClearKey:
- return DoMarkOthersRead(wind);
- case kKeypadEqualKey:
- DoSelectAll(wind);
- return noErr;
- case kKeypadSlashKey:
- return DoExpandCollapseSelectedThread(wind);
- case kKeypadStarKey:
- return DoClose(wind);
- case kKeypadMinusKey:
- return DoMarkCommand(wind, false);
- case kKeypadPlusKey:
- return DoMarkCommand(wind, true);
- case kKeypadEnterKey:
- return DoNextGroup(wind);
- case kKeypadPeriodKey:
- return DoNextThread(wind);
- case kKeypad0Key:
- return DoNextArticle(wind);
- case kKeypad1Key:
- Scroll(wind, kScrollToEnd);
- return noErr;
- case kKeypad2Key:
- Scroll(wind, inDownButton);
- return noErr;
- case kKeypad3Key:
- Scroll(wind, inPageDown);
- return noErr;
- case kKeypad5Key:
- return DoNextArticle(wind);
- case kKeypad7Key:
- Scroll(wind, kScrollToHome);
- return noErr;
- case kKeypad8Key:
- Scroll(wind, inUpButton);
- return noErr;
- case kKeypad9Key:
- Scroll(wind, inPageUp);
- return noErr;
- default:
- SysBeep(0);
- return noErr;
- }
- }
-
- if (theChar == pageUpKey) {
- Scroll(wind, inPageUp);
- return noErr;
- }
- if (theChar == pageDownKey) {
- Scroll(wind, inPageDown);
- return noErr;
- }
- if (theChar == homeKey) {
- Scroll(wind, kScrollToHome);
- return noErr;
- }
- if (theChar == endKey) {
- Scroll(wind, kScrollToEnd);
- return noErr;
- }
- if (theChar == returnKey || theChar == enterKey) {
- return OpenSelectedCells(wind);
- }
-
- if (theChar == upArrow || theChar == downArrow) {
- ListArrowKey(theChar, modifiers, theList, &gPrevEvent, &scrollIntoView);
- HandleUpdate(wind);
- MyLScrollCellIntoView(scrollIntoView, theList);
- return noErr;
- }
-
- if (gPrefs.keyboardShortcuts) {
-
- theChar = tolower(theChar);
-
- if (theChar == ' ' || theChar == 'n' || theChar == 'i') {
- return DoNextArticle(wind);
- }
-
- if (theChar == 't') {
- return DoNextThread(wind);
- }
-
- if (theChar == 'g' || theChar == 'j') {
- return DoNextGroup(wind);
- }
-
- if (theChar == 'w') {
- return DoClose(wind);
- }
-
- if (theChar == 'u') {
- return DoMarkCommand(wind, false);
- }
-
- if (theChar == 'm') {
- return DoMarkCommand(wind, true);
- }
-
- if (theChar == 'a') {
- DoSelectAll(wind);
- return noErr;
- }
-
- if (theChar == ';') {
- return DoMarkOthersRead(wind);
- }
-
- }
-
- SysBeep(0);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Grow
-
- Handle a mouse down event in the grow box of a subject window.
-
- Entry: wind = pointer to subject window.
- where = location of mouse down event, in global coordinates.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Grow (WindowPtr wind, Point where)
- {
- Rect sizeRect;
- long size;
- short width, height;
-
- SetRect(&sizeRect, kMinWindowWidth, MinHeight(wind), 0x7fff, 0x7fff);
- size = GrowWindow(wind, where, &sizeRect);
-
- if (size != 0) {
- width = LoWord(size);
- height = HiWord(size);
- FixHeight(wind, &height);
- SizeWindow(wind, width, height, false);
- ResizeContents(wind);
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Zoom
-
- Zoom a subject window.
-
- Entry: wind = pointer to subject window.
- zoomDir = zoom direction = inZoomIn or inZoomOut.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Zoom (WindowPtr wind, short zoomDir)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray, *pSubjectArray;
- Handle strings;
- short width, height, lineHeight, minHeight, panelHeight, i, len;
- short subjectWidth, maxSubjectWidth, numCells, numSubjects;
- char *subject;
- Rect zoomRect;
- WStateData **wState;
- long longHeight;
- char state1, state2;
-
- wState = (WStateData**)((WindowPeek)wind)->dataHandle;
- if (zoomDir == inZoomOut) {
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- panelHeight = (**info).panelHeight;
- subjectArray = (**info).subjectArray;
- strings = (**info).strings;
- numCells = (**theList).dataBounds.bottom;
- lineHeight = (**theList).cellSize.v;
- maxSubjectWidth = (**info).maxSubjectWidth;
- numSubjects = (**info).numSubjects;
-
- if (maxSubjectWidth == 0) {
- state1 = MyHGetState(strings);
- state2 = MyHGetState(subjectArray);
- MyHLock(strings);
- MyHLock(subjectArray);
- for (i = 0, pSubjectArray = *subjectArray; i < numSubjects; i++, pSubjectArray++) {
- if (pSubjectArray->inList) {
- subject = *strings + pSubjectArray->subjectOffset;
- len = strlen(subject);
- if (len > 80) len = 80;
- subjectWidth = TextWidth(subject, 0, len);
- if (subjectWidth > maxSubjectWidth) maxSubjectWidth = subjectWidth;
- }
- }
- MyHSetState(strings, state1);
- MyHSetState(subjectArray, state2);
- (**info).maxSubjectWidth = maxSubjectWidth;
- }
- width = maxSubjectWidth + (**info).subjectHCoord + 24;
- if (width < kMinWindowWidth) width = kMinWindowWidth;
-
- longHeight = (long)numCells * (long)lineHeight + panelHeight + 15;
- if (longHeight > 0x7fff) {
- height = 0x7fff;
- } else {
- height = longHeight;
- minHeight = MinHeight(wind);
- if (height < minHeight) height = minHeight;
- }
-
- CalculateZoomRect(wind, width, height, &zoomRect, gPrefs.dontCoverFinderIcons);
- height = zoomRect.bottom - zoomRect.top;
- FixHeight(wind, &height);
- zoomRect.bottom = zoomRect.top + height;
- (**wState).stdState = zoomRect;
- if (WindRectEqualRect(wind, &zoomRect)) return noErr;
- }
-
- EraseRect(&wind->portRect);
- ZoomWindow(wind, zoomDir, false);
- ResizeContents(wind);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Command
-
- Handle a command for a subject window.
-
- Entry: wind = pointer to subject window.
- menu = the menu.
- item = the item.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Command (WindowPtr wind, short menu, short item, short modifiers)
- {
- OSErr err = noErr;
-
- switch (menu) {
-
- case kFileMenu:
-
- switch (item) {
- case kSaveItem:
- err = DoSave(wind, modifiers);
- break;
- case kSaveAsItem:
- err = DoSaveAs(wind);
- break;
- case kAppendItem:
- err = DoAppend(wind);
- break;
- case kPrintItem:
- err = DoPrint(wind);
- break;
- }
- break;
-
- case kEditMenu:
-
- switch (item) {
- case kSelectAllItem:
- DoSelectAll(wind);
- break;
- case kDeselectAllItem:
- DoDeselectAll(wind);
- break;
- case kFindItem:
- err = DoFind(wind);
- break;
- case kFindAgainItem:
- err = DoFindAgain(wind);
- break;
- }
- break;
-
- case kNewsMenu:
-
- switch (item) {
- case kNextArticleItem:
- err = DoNextArticle(wind);
- break;
- case kNextThreadItem:
- err = DoNextThread(wind);
- break;
- case kNextGroupItem:
- err = DoNextGroup(wind);
- break;
- case kMarkReadItem:
- err = DoMarkCommand(wind, true);
- break;
- case kMarkUnreadItem:
- err = DoMarkCommand(wind, false);
- break;
- case kMarkOthersReadItem:
- err = DoMarkOthersRead(wind);
- break;
- case kReplyItem:
- err = DoReply(wind, modifiers);
- break;
- case kForwardItem:
- err = DoForward(wind, modifiers);
- break;
- case kRedirectItem:
- err = DoRedirect(wind, modifiers);
- break;
- }
- break;
-
- case kSpecialMenu:
-
- switch (item) {
- case kExtractBinariesItem:
- err = DoExtractBinaries(wind, modifiers);
- break;
- case kExtractBinariesManuallyItem:
- err = DoExtractBinariesManually(wind, modifiers);
- break;
- case kSearchItem:
- err = DoSearch(wind);
- break;
- case kCancelArticleItem:
- err = DoCancelArticle(wind);
- break;
- }
- }
-
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Close
-
- Close a subject window.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Close (WindowPtr wind)
- {
- TWindow **info;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
-
- while ((**info).childList != nil) {
- err = DoClose((**(**info).childList).childWindow);
- if (err != noErr) return err;
- }
- RemoveChild((**info).parentWindow, wind);
-
- err = UpdateUnreadList(wind);
- if (err != noErr) return err;
-
- if ((**info).theList != nil) LDispose((**info).theList);
- MyDisposeHandle((**info).subjectArray);
- MyDisposeHandle((**info).sortByNumber);
- MyDisposeHandle((**info).strings);
- if ((**info).collapseTriangle != nil) KillPoly((**info).collapseTriangle);
- if ((**info).expandTriangle != nil) KillPoly((**info).expandTriangle);
- MyDisposeHandle(info);
-
- MyDisposeWindow(wind);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Idle
-
- Handle idle time tasks for a subject window.
-
- Entry: wind = pointer to subject window.
-
- Exit: cursorRgn = cursor region for WaitNextEvent mouse moved events.
- ----------------------------------------------------------------------------*/
-
- static void Idle (WindowPtr wind, RgnHandle cursorRgn)
- {
- TWindow **info;
- ListHandle theList;
- unsigned long fileEnabled, editEnabled, newsEnabled, specialEnabled;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- SetCursor(&qd.arrow);
- fileEnabled = kSubjectFileEnabled;
- editEnabled = kSubjectEditEnabled;
- newsEnabled = kSubjectNewsEnabled;
- specialEnabled = kSubjectSpecialEnabled;
- if ((**theList).dataBounds.bottom == 0)
- editEnabled &= ~kSelectAllMask;
- if (!ListHasSelectedCell(theList)) {
- editEnabled &= ~kDeselectAllMask;
- fileEnabled &= ~(kSaveMask | kSaveAsMask | kAppendMask | kPrintMask);
- newsEnabled &= ~(kMarkReadMask | kMarkUnreadMask | kMarkOthersReadMask |
- kReplyMask | kForwardMask | kRedirectMask);
- specialEnabled &= ~(kExtractBinariesMask |
- kExtractBinariesManuallyMask | kCancelArticleMask);
- }
- if (*gFindPattern == 0) editEnabled &= ~kFindAgainMask;
- SetMenusTo(kAppleAllEnabled, fileEnabled, editEnabled,
- newsEnabled, specialEnabled, kSubjectWindEnabled);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Help
-
- Handle help balloons for a subject window.
-
- Entry: wind = pointer to subject window.
- where = current mouse location in local coordinates.
- ----------------------------------------------------------------------------*/
-
- static void Help (WindowPtr wind, Point where)
- {
- TWindow **info;
- Rect r;
- Point tip = {0,0};
- short subjectAuthorHCoord, x, y;
- short panelHeight, visTop, cellHeight, cellDataLen, index;
- TSubject theSubject;
- TSubject **subjectArray;
- FontInfo fontInfo;
- Cell theCell;
- ListHandle theList;
-
- if (DoSizeBoxAndVerticalScrollBarBalloons(wind, where)) return;
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- theList = (**info).theList;
- visTop = (**theList).visible.top;
- cellHeight = (**theList).cellSize.v;
- subjectArray = (**info).subjectArray;
- GetFontInfo(&fontInfo);
- SetRect(&r, 0, wind->portRect.bottom - 14, 15, wind->portRect.bottom);
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(tip, &r, (**info).windPosLocked ? 23 : 22);
- return;
- }
- subjectAuthorHCoord = (**info).authorsShown ?
- (**info).authorHCoord : (**info).subjectHCoord;
- SetRect(&r, subjectAuthorHCoord,
- panelHeight,
- wind->portRect.right - 15,
- wind->portRect.bottom - 15);
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(where, &r, (**info).authorsShown ? 14 : 15);
- return;
- }
- x = ((**info).threadCountHCoord + (**info).checkHCoord) >> 1;
- r.left = x;
- r.right = subjectAuthorHCoord;
- if (PtInRect(where, &r)) {
- SetPt(&tip, (r.left + r.right) >> 1, where.v);
- ShowHelpBalloon(tip, &r, 21);
- return;
- }
- y = (**theList).indent.h + fontInfo.ascent;
- r.left = y;
- r.right = x;
- if (PtInRect(where, &r)) {
- SetPt(&tip, (r.left + r.right) >> 1, where.v);
- ShowHelpBalloon(tip, &r, 20);
- return;
- }
- SetRect(&r, 0, 0, y, 0);
- if (where.h > r.right) return;
- if (!PtInListCell(where, theList)) return;
- theCell.h = 0;
- theCell.v = (where.v - panelHeight)/cellHeight + visTop;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- r.top = (theCell.v - visTop) * cellHeight + panelHeight;
- r.bottom = r.top + cellHeight;
- if (theSubject.threadLength == 1) {
- ShowHelpBalloon(tip, &r, 18);
- } else if (theSubject.threadOrdinal > 1) {
- ShowHelpBalloon(tip, &r, 19);
- } else if (theSubject.collapsed) {
- ShowHelpBalloon(tip, &r, 16);
- } else {
- ShowHelpBalloon(tip, &r, 17);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- InitSubjectDispatchTable
-
- Initialize the dispatch table for subject windows.
- ----------------------------------------------------------------------------*/
-
- void InitSubjectDispatchTable (void)
- {
- TDispatch *d;
-
- d = &gDispatch[kSubject];
-
- d->activate = Activate;
- d->update = Update;
- d->mouse = Mouse;
- d->draggable = Draggable;
- d->key = Key;
- d->grow = Grow;
- d->zoom = Zoom;
- d->command = Command;
- d->close = Close;
- d->idle = Idle;
- d->help = Help;
-
- gExtractBinariesManuallyClickLoopUPP =
- NewListClickLoopProc(ExtractBinariesManuallyClickLoop);
- gOldListClickLoopUPP =
- NewListClickLoopProc(OldListClickLoop);
- gSubjectListClickLoopUPP =
- NewListClickLoopProc(SubjectListClickLoop);
- gExtractBinariesManuallyHandleTrackingUPP =
- NewDragTrackingHandlerProc(ExtractBinariesManuallyHandleTracking);
- gExtractBinariesManuallyHandleReceiveUPP =
- NewDragReceiveHandlerProc(ExtractBinariesManuallyHandleReceive);
- gDragSubjectsSendProcUPP =
- NewDragSendDataProc(DragSubjectsSendProc);
- gExtractBinariesManuallyDialogFilterUPP =
- NewModalFilterProc(ExtractBinariesManuallyDialogFilter);
- gExtractBinariesManuallyDlgLabelUserItemUPP =
- NewUserItemProc(ExtractBinariesManuallyDlgLabelUserItem);
- gExtractBinariesManuallyDlgListUserItemUPP =
- NewUserItemProc(ExtractBinariesManuallyDlgListUserItem);
- }
-